home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 141_01 / hdwlib.c < prev    next >
Text File  |  1985-03-09  |  15KB  |  470 lines

  1. /* hdwlib.c -- hardware library -- contents:    1984 may 4
  2.     read & set date/time - Newclock80
  3.          primitives for graphics peripheral - TMS9918a
  4.     cursor-control for TRS-80 screen w/ Omikron bios
  5.     PM Krasno 17813 Kiowa Trail Los Gatos CA 95030
  6. */
  7.  
  8. #include "bdscio.h"
  9. #define short char
  10. #define byte char
  11. #define K 1024
  12.  
  13. /* -- fcns to read & set Newclock80    */
  14.  
  15. unsigned tim_dif (d, t1, t2) char *d, *t1, *t2 ; 
  16. /* time difference in seconds, up to 18hrs or so */ {
  17.     char *t ; int n ; unsigned dif ;
  18.     unsigned val[12] ; /* seconds, each digit-position */
  19.     val[6] = 36000 ;    val[7] =  3600 ; /* hrs */
  20.     val[8] =   600 ;    val[9] =    60 ; /* min */
  21.     val[10] =   10 ;    val[11] =    1 ; /* sec */
  22.      n = 0 ; /* digit counter */
  23.     while ( t1[n] && t1[n] == t2[n] ) /* leading zeroes */
  24.         ++n ; 
  25.     if ( t1[n] < t2[n] ) /* if negative, swap pointers */
  26.         { t = t1 ; t1 = t2 ; t2 = t  ; }
  27.     if ( n < 6 ) return 65535 ; /* error - day changed */
  28.     for (dif = 0 ; n < 12 ; ++n)
  29.         dif += val[n] * (t1[n] - t2[n]) ;    
  30.     return dif ;
  31. } /* tim_dif */
  32.  
  33. #define clock_port 0xB0        /* Newclock80 base port */
  34. #define clock_digs 13        /* # data digits    */
  35.  
  36. syst_d (d) char *d ; { /* system date/time, "yymddhhmmss" */
  37. /* read Newclock80, ASCII format    */
  38. #define day_dig 6
  39.     /* compare tens of seconds before & after,
  40.         in case of rollover */
  41.     byte bef, aft ; int i, j ;
  42.  
  43.     aft = 0xF & inp (clock_port + 1) ;
  44.     do {    bef = aft ;
  45.         for (i = clock_digs - 1, j = 0 ; 0 <= i ; 
  46.             --i, ++j )
  47.             if ( i == day_dig ) --j ; /* skip weekday*/
  48.             else d[j] = '0' + (inp (clock_port + i) &
  49.             (((j==4) | (j==6)) ? 0x3 : 0xF) ) ;
  50.         aft = 0xF & inp (clock_port + 1) ;
  51.     } while ( bef != aft ) ;
  52.     d[clock_digs-1] = 0 ;
  53. #undef day_dig
  54. } /* sys_d */
  55.  
  56. read_clock (d_t) byte *d_t ;    {
  57.     /* compare tens of seconds before & after,
  58.         in case of rollover */
  59.     byte tens_bef, tens_aft ; int i, j ;
  60.  
  61.     tens_aft = 0xF & inp (clock_port + 1) ;
  62.     do {    tens_bef = tens_aft ;
  63.         for (i = clock_digs - 1, j = 0 ; 0 <= i ; 
  64.             --i, ++j )
  65.             d_t[j] = 0xF & inp (clock_port + i) ;
  66.         tens_aft = 0xF & inp (clock_port + 1) ;
  67.     } while ( tens_bef != tens_aft ) ;
  68. } /* read_clock */
  69.  
  70. show_clock (d_t) byte *d_t ;    {
  71.     int i, j, digit ; char *ptr ;
  72.     ptr = "SunMonTueWedThuFriSat" ;    /* quasi-static */
  73.     for (i = clock_digs, j = 0 ; 0 < i ; --i, ++j)    {
  74.         digit = d_t[j] ;
  75.         switch (j)    { 
  76.         case 4:        digit &= 0x3 ;
  77.         case 2:          puts ("/") ; break ;
  78.         case 7:        digit &= 0x3 ; break ;
  79.         case 9: case 11: puts (":") ; break ;
  80.         default : ;    } /* punctuation, masking */
  81.         if ( j != 6 ) putchar (0x30 + digit) ;
  82.         else printf (" %3.3s ",
  83.             ptr + 3 * (0x7 & digit)) ;
  84.     } /* for all digits */
  85.     putchar ('\n') ;
  86. } /* show_clock */
  87.  
  88. set_clock (d_t, n) byte *d_t ; int n ;    { /* n = offset */
  89.     int i, j ;
  90.     for (i = clock_digs - 1 - n, j = n ; 0 <= i ; --i, ++j)
  91.         outp (clock_port + j, 0xF & d_t[i]) ;
  92. } /* set_clock */
  93. #undef clock_digs
  94. #undef clock_port
  95.  
  96. /*  - primitives for CHROMAtrs/TMS9918A graphics */
  97. /* after an .asm package marked 
  98.     "(c) 1982 South Shore Computer Concepts, Hewlett, NY"
  99.     rewritten (NOT copied!) in BDS C 1983 Sep pmk */
  100. /* vram addresses cleaned up, text mode added 1984 may pmk */
  101. #define stat_port 0x79        /* CHROMAtrs port address */
  102. #define reg_port  0x79
  103. #define add_port  0x79
  104. #define data_port 0x78        /* CHROMAtrs vram read/write */
  105. #define STICK     0x7D        /* joystick */
  106. #define ena_port  0xEC        /* TRS-80 MOD III I/O BUS */
  107. #define PAT_GEN    0    /* pattern gen vram loc    */
  108. #define PAT_NAM    0x1800    /* pattern name table      */
  109. #define SPR_ATT    0x1C00    /* sprite attribute table  */
  110. #define PAT_COL    0x2000    /* pattern color table     */
  111. #define SPR_PAT    0x3800    /* sprite pattern table    */
  112. #define WH 15    /* colors */
  113. #define BL 1
  114.  
  115. vram_out (addr, data)    /* output to vram thru tms9918a */
  116. unsigned addr, data ;    {
  117. /*M III    outp (ena_port, 0x10) ; */    inp (stat_port) ;
  118.     outp (reg_port, 0xFF & addr) ;    /* LSB */
  119.     outp (reg_port, 0x40 | (0x3F & (addr>>8 ))) ;
  120.         /* MSB, flags (asm needs NOP for timing ? */
  121.     outp (data_port, data) ;    /* 1st data byte */
  122. } /* vram_out */
  123.  
  124. vram_o_m (addr, data, count) /* out data byte count times */
  125. unsigned addr, data, count ;    {
  126. /*M III    outp (ena_port, 0x10) ; */    inp (stat_port) ;
  127.     outp (reg_port, 0xFF & addr) ;
  128.     outp (reg_port, 0x40 | (0x3F & (addr>>8) ) ) ;
  129.     while ( count-- ) outp (data_port, data) ;
  130. } /* vram_o_m */
  131.  
  132. vram_o_2 (addr, data1, data2) /* out 2 data bytes */
  133. unsigned addr, data1, data2 ;    {
  134. /*M III    outp (ena_port, 0x10) ; */    inp (stat_port) ;
  135.     outp (reg_port, 0xFF & addr) ;
  136.     outp (reg_port, 0x40 | (0x3F & (addr>>8) ) ) ;
  137.     outp (data_port, data1) ;
  138.     outp (data_port, data2) ;
  139. } /* vram_o_2 */
  140.  
  141. vram_o_a (addr, pdata, count) /* out count bytes from array */
  142. unsigned addr, count ; char *pdata ;    {
  143. /*M III    outp (ena_port, 0x10) ; */    inp (stat_port) ;
  144.     outp (reg_port, 0xFF & addr) ;
  145.     outp (reg_port, 0x40 | (0x3F & (addr>>8) ) ) ;
  146.     while ( count-- ) outp (data_port, *pdata++) ;
  147. } /* vram_o_a */
  148.  
  149. int vram_in (addr)    /* input from vram thru tms9918a */
  150. unsigned addr ;    {
  151. /*M III    outp (ena_port, 0x10) ; */    inp (stat_port) ;
  152.     outp (reg_port, 0xFF & addr) ;    /* LSB */
  153.     outp (reg_port, 0x3F & (addr>>8) ) ;
  154.     return inp (data_port) ;
  155. } /* vram_in */
  156.  
  157. vram_i_a (addr, pdata, count)    /* input count bytes */
  158. unsigned addr, count ; char *pdata ;    {
  159. /*M III    outp (ena_port, 0x10) ; */    inp (stat_port) ;
  160.     outp (reg_port, 0xFF & addr) ;
  161.     outp (reg_port, 0x3F & (addr>>8) ) ;
  162.     while ( count-- ) *pdata++ = inp (data_port) ;
  163. } /* vram_i_a */
  164.  
  165. vreg_out (reg, data)    /* output to vreg in tms9918a */
  166. unsigned reg, data ;    {
  167. /*M III    outp (ena_port) ; */    inp (stat_port) ;
  168.     outp (reg_port, data) ;        /* data */
  169.     outp (reg_port, 0x80 | reg) ;    /* reg #, flag */
  170. } /* vreg_out */
  171.  
  172. txt_mod ()    /* set up tms9918 text mode */    {
  173.     byte reg[8] ;    int i, j ;
  174.     reg[0] = 0x00 ;    /* M3 = 0, no video in */
  175.     reg[1] = 0x80 | 0x10 | 0x02 ;
  176.         /* 4116, blank, M1=1, size 8, mag 1X */
  177.     reg[2] = PAT_NAM / 0x400 ;    /* PAT_NAM msb */
  178.     reg[3] = PAT_COL / 0x40 ;    /* PAT_COL msb */
  179.     reg[4] = PAT_GEN / 0x800 ;    /* PAT_GEN msb */
  180.     reg[5] = SPR_ATT / 0x80 ;    /* SPR_ATT msb */
  181.     reg[6] = SPR_PAT / 0x80 ;    /* SPR_PAT msb */
  182.     reg[7] = (WH << 4) | BL ;    /* text, bkgr color */
  183.     for (i = 7 ; 0 <= i ; --i)
  184.         vreg_out (i, reg[i]) ;
  185.     vram_o_m (0, 0, 16 * K) ;
  186.     vram_o_m (PAT_NAM, ' ', 40 * 24) ;
  187.     txt_font ("b:font.def") ; 
  188.     vreg_out (1, reg[1] | 0x40) ; /* un-blank */
  189. } /* txt_mod */
  190.  
  191. txt_font (file)    char *file ; {
  192. #define FSIZ 0x60
  193.     byte font[FSIZ][6] ; 
  194.     /* vertical dot-matrix images, 6 bytes/char */ 
  195.     char fontbuf[BUFSIZ] ;    int ifont[6], c, i, s ;
  196.     if (fopen (file, fontbuf) == ERROR)
  197.         printf ("%s ?\n", file) ;
  198.     while (TRUE)    {    /* one pattern per line, to EOF */
  199.         s = fscanf (fontbuf,
  200.             "%x: %x, %x, %x, %x, %x, %x, %x, %x ;",
  201.             & c, ifont, ifont+1, ifont+2,
  202.              ifont+3, ifont+4, ifont+5) ;
  203.         if (s == EOF || s == CPMEOF || c ==0xff) break;
  204.         else if (s == 7 && ' ' <= c && c <= 0x7f)  {
  205.             for (i = 5 ; i >= 0 ; i--)
  206.                 font[c-' '][i] = ifont[i] ;
  207.         } /* if good char */
  208.         else    printf ("trouble in %s at %02x\n",
  209.                 file, c) ;
  210.     } /* loop until EOF */
  211.     fclose (fontbuf) ;
  212.     wr_font (font) ;
  213. } /* txt_font */
  214.  
  215. wr_font (font) byte font[FSIZ][6] ; { /* write font to vram */
  216.     int i, j, k ; byte f[FSIZ][8] ;
  217.     for (i = FSIZ-1 ; 0 <= i ; --i)    /* transpose */
  218.         for (k = 0 ; k < 8 ; ++k)    /* row */
  219.         for (f[i][k] = j = 0 ; j < 6 ; ++j) /* col */
  220.             f[i][k] |=
  221.              ( (font[i][j] << (7-k) ) & 0x80) >> j ;
  222.     vram_o_a (PAT_GEN + 8 * ' ', f, FSIZ * 8) ;
  223. } /* wr_font */
  224. #undef FSIZ
  225.  
  226. txt_ch (l, c, ch) int l, c ; char ch ; { /* write text char */
  227.     vram_out (PAT_NAM + 40 * (l-1) + c-1, ch) ;
  228. } /* txt_ch */
  229.  
  230. sh_ch (f) char *f ; {
  231.     int r, c ;
  232.     for (printf("\N"),r=0 ; r<8 ; ++r, printf("\N") )
  233.         for (c=0 ; c<8 ; ++c)
  234.             printf("%s", f[r] & (0x80 >> c) ? 
  235.                 "**":"  ") ;
  236. } /* sh_ch */
  237.  
  238. mode2 ()    /* set up tms9918 graphics mode 2 */    {
  239.     byte reg[7] ;    int i ;
  240.     reg[0] = 0x02 ;    /* M3 = 1, no video in */
  241.     reg[1] = 0x80 | 0x40 | 0x02 ;
  242.         /* 4116, active, size 8, mag 1X */
  243.     reg[2] = PAT_NAM / 0x400 ;    /* PAT_N